#include "tcpsocket.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

using namespace VLRTSP;

/**
 * @Author: CimZzz
 * @Date: 2022-01-10 16:47:47
 * 
 * 构造函数
 * @param fd Socket Fd
 * @param ip IP 地址
 * @param port 端口号
 */
TCPSocket::TCPSocket(VL_SOCKET fd, std::string ip, uint16_t port): ip(ip) {
	this->fd = fd;
	this->port = port;
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-10 16:48:04
 * 
 * 析构函数
 */
TCPSocket::~TCPSocket() {
	if(fd > 0) {
		// 关闭 Socket 套接字
		::close(fd);
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-10 16:21:42
 * 
 * 读取套接字中的字节
 * @param buffer 接收读取的字节缓冲区
 * @param size 指定读取的字节长度，0 表示读取任意长度
 * @return 读取成功返回读取长度，-1 表示读取失败
 */
int64_t TCPSocket::read(Buffer* buffer, uint32_t size) {
	if(fd > 0 && buffer != nullptr) {
		if(size > 0) {
			uint8_t readBuffer[size];
			uint32_t needReadSize = size;
			int64_t totalSize = 0;
			int64_t readSize = 0;

			READ:
			readSize = ::read(fd, readBuffer + totalSize, needReadSize);
			if(readSize <= 0) {
				return -1;
			}

			totalSize += readSize;
			needReadSize -= readSize;
			if(needReadSize < 0) {
				return -1;
			}

			if(readSize == 0 || needReadSize == 0) {
				buffer->appendBuffer(readBuffer, 0, size);
				return totalSize;
			}
			goto READ;	
		} else {
			uint8_t readBuffer[255];
			int64_t readSize = ::read(fd, readBuffer, 255);
			if(readSize <= 0) {
				return -1;
			}
			buffer->appendBuffer(readBuffer, 0, readSize);
			return readSize;
		}
	}
	else {
		return -1;
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-10 16:46:19
 * 
 * 写字节缓冲区中的字节
 * @param buffer 字节缓冲区
 * @return 如果写入成功返回 true
 */
bool TCPSocket::write(Buffer* buffer) {
	if(fd > 0 && buffer != nullptr) {
		uint8_t* realBuffer = buffer->getBuffer();
		uint32_t needWriteSize = buffer->getBufferLength();
		int64_t totalSize = 0;
		uint32_t writeSize = 0;
		WRITE:
		writeSize = ::write(fd, realBuffer + totalSize, needWriteSize);
		if(writeSize < 0) {
			return false;
		}
		totalSize += writeSize;
		needWriteSize -= writeSize;
		if(needWriteSize < 0) {
			return false;
		}
		if(writeSize == 0 || needWriteSize == 0) {
			return true;
		}
		goto WRITE;
	}
	else {
		return false;
	}
}


/**
 * @Author: CimZzz
 * @Date: 2022-01-10 19:29:13
 * 
 * 关闭 Socket
 */
void TCPSocket::close() {
	if(this->fd != -1) {
		::close(this->fd);
		this->fd = -1;
	}
}


/**
 * @Author: CimZzz
 * @Date: 2022-01-11 15:37:17
 * 
 * 获取 Socket Id
 */
VL_SOCKET TCPSocket::getSocketId() {
	return this->fd;
}